#ifndef __SLIST_H__
#define __SLIST_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAGIC "slist"
#define SIZE 32
#define  DEBUG(msg) printf("file: %s func: %s line: %d "msg, __FILE__, __func__, __LINE__)

//函数指针类型
typedef int(*op_t)(void *data);
typedef int(*cmp_t)(void *data, void *key);
typedef int(*op_file_t)(void *data, FILE *fp);

//链表的节点类型
typedef struct _node_t{
    void *data;             //数据域
    struct _node_t *next;   //指针域
}node_t;

//链表的头信息结构体
typedef struct _slist_t{
    node_t *p;          //指向链表的第一个节点
    int size;           //数据的大小
    int count;          //节点的个数
    op_t my_destroy;    //自定义销毁函数
}slist_t;


//头信息结构体的创建
slist_t *slist_create(int size, op_t my_destroy);
//头插
int slist_prepend(slist_t *s, void *data);
//尾插
int slist_append(slist_t *s, void *data);
//通过索引插入
int slist_insert_by_index(slist_t *s, void *data, int index);

//返回链表中节点的个数
int slist_count(slist_t *s);

//通过索引检索值
int slist_retrieve_by_index(slist_t *s, void *data, int index);
//通过关键字检索值
int slist_retrieve_by_key(slist_t *s, void *data, void *key, cmp_t my_cmp);
//通过关键字查找索引
int slist_find_index_by_key(slist_t *s, void *key, cmp_t my_cmp);
//通过关键字查找所有的索引
slist_t *slist_find_all_index_by_key(slist_t *s, void *key, cmp_t my_cmp);


//通过索引修改对应的结点的数据
int slist_modify_by_index(slist_t *s, void *data, int index);
//通过关键字修改对应的结点的数据
int slist_modify_by_key(slist_t *s, void *data, void *key, cmp_t op_cmp);
//功过关键字修改所有的结点的数据
int slist_modify_all_by_key(slist_t *s, void *data, void *key, cmp_t op_cmp);


//通过索引删除链表的结点
int slist_delete_by_index(slist_t *s, int index);
//通过关键字删除链表的结点
int slist_delete_by_key(slist_t *s, void *key, cmp_t op_cmp);
//通过关键字删除链表中所有匹配的结点
int slist_delete_all_by_key(slist_t *s, void *key, cmp_t op_cmp);


//保存链表中的数据到指定的文件中
int slist_store(slist_t *s, const char *path, op_file_t op_store);
//从指定的文件中加载链表的数据
int slist_load(slist_t *s, const char *path, op_file_t op_load);


//链表的反转
int slist_reverse(slist_t *s);

//遍历
int slist_traverse(slist_t *s, op_t my_print);
//销毁
int slist_destroy(slist_t *s);

#endif




